#pragma once
#include "rpcRoute.hpp"
#include "../client/register.hpp"

class RpcServer
{
public:
    using ptr = std::shared_ptr<RpcServer>;
    RpcServer(const Address &localAddr, const Address &registerServer, uint8_t localServerIoThreads = 5, const std::string &localServerName = "RpcServer", bool localServerReusePort = true, const std::string &registerClientName = "RegisterClient")
        : _dispatcher(new Dispatcher), _register(new RegisterClient(registerServer, registerClientName, _dispatcher)), _rpcRoute(new RpcRoute), _netServer(NetFactory::creater<MuduoServer>(localAddr.first, localAddr.second, localServerName, localServerReusePort))
    {
        _netServer->setIoThreads(localServerIoThreads);
        _netServer->setHandlerProtocol(ProtocolFactory::create<LvProtocol>());
        _netServer->setMessageHander(std::bind(&Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
        _netServer->setConnCb(std::bind(&RpcServer::onConnection, this, std::placeholders::_1));
        _netServer->setCloseCb(std::bind(&RpcServer::closed, this, std::placeholders::_1));

        _dispatcher->setCallBack<RPCRequest>(MSG_Type::RPC_REQ, std::bind(&RpcRoute::onRpcReauest, _rpcRoute.get(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    }

    // 连接注册中心
    void connectRegister()
    {
        _register->connect();
        while (true)
        {
            if (!_register->connected())
            {
                LOG_DEBUG << "正在连接注册中心...";
            }
            else
            {
                 LOG_DEBUG << "连接到注册中心: " << _register->getPerrAddress();
                break;
            }
            sleep(1);
        }
    }

    void start()
    {
        _netServer->start();
    }

    // 服务操作接口
    void registerMethod(CallDescription::ptr des)
    {
        if (des->check())
        {
            _register->opMethod(SERVICE_OPTYPE::REGISTER, des->getMethodName(), des->getAddress());
            _rpcRoute->setMethodToFunc(des->getMethodName(), des);
        }
    }

    void onlineMethod(CallDescription::ptr des)
    {
        if (des->check())
        {
            _register->opMethod(SERVICE_OPTYPE::ONLINE, des->getMethodName(), des->getAddress());
        }
    }

    void offlineMethod(CallDescription::ptr des)
    {
        if (des->check())
        {
            _register->opMethod(SERVICE_OPTYPE::OFFLINE, des->getMethodName(), des->getAddress());
            _rpcRoute->delMethodToFun(des->getMethodName());
        }
    }

private:
    void onConnection(BaseConnection::ptr conn)
    {
        LOG_DEBUG << "建立连接：" << conn->perrAddressString();
    }

    void closed(BaseConnection::ptr conn)
    {
        LOG_DEBUG << "连接断开：" << conn->perrAddressString();
    }

private:
    Dispatcher::ptr _dispatcher;   // 共用模块
    RegisterClient::ptr _register; // 服务注册/上线/下线客户端

    RpcRoute::ptr _rpcRoute;
    BaseNet::ptr _netServer; // rpc 服务端
};